package cn.wolfcode.wms.service.impl;

import cn.wolfcode.wms.domain.*;
import cn.wolfcode.wms.mapper.ProductStockMapper;
import cn.wolfcode.wms.mapper.StockIncomeBillItemMapper;
import cn.wolfcode.wms.mapper.StockIncomeBillMapper;
import cn.wolfcode.wms.query.QueryObject;
import cn.wolfcode.wms.service.IStockIncomeBillService;
import cn.wolfcode.wms.util.PageResult;
import cn.wolfcode.wms.util.UserContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;
import java.util.Optional;

@Service
public class StockIncomeBillServiceImpl implements IStockIncomeBillService {
    @Autowired
    private StockIncomeBillMapper billMapper;
    @Autowired
    private StockIncomeBillItemMapper itemMapper;
    @Autowired
    private ProductStockMapper psMapper;


    @Override
    public void saveOrUpdate(StockIncomeBill entity) {
        if (!Optional.ofNullable(entity.getId()).isPresent()) {
            saveBill(entity);
        } else {
            updateBill(entity);
        }
    }



    //更新单据的业务操作
    private void updateBill(StockIncomeBill entity) {
        StockIncomeBill old = billMapper.selectByPrimaryKey(entity.getId());
        //判断当前单据必须是未审核状态
        if (entity.getStatus() == StockIncomeBill.NO_AUDITED) {
            //删除旧的明细
            billMapper.deleteItemsByBillId(entity.getId());
            //重新计算新的小计和总计
            BigDecimal totalNumber = BigDecimal.ZERO;
            BigDecimal totalAmount = BigDecimal.ZERO;
            for (StockIncomeBillItem item : entity.getItems()) {
                BigDecimal amount = item.getCostPrice().multiply(item.getNumber())
                        .setScale(2, RoundingMode.HALF_UP);
                item.setAmount(amount);
                totalNumber = totalNumber.add(item.getNumber());
                totalAmount = totalAmount.add(amount);
                //最后,直接保存新的明细
                item.setBillId(entity.getId());
                itemMapper.insert(item);
            }
            old.setTotalNumber(totalNumber);
            old.setTotalAmount(totalAmount);
            //同步新的数据
            old.setSn(entity.getSn());
            old.setVdate(entity.getVdate());
            old.setDepot(entity.getDepot());
            //更新单据
            billMapper.updateByPrimaryKey(old);
        }
    }

    //新增单据的业务操作
    private void saveBill(StockIncomeBill entity) {
        //判断至少有一个明细
        if (entity.getItems().size() == 0) {
            throw new RuntimeException("至少要有一条明细");
        }
        //所有的关键信息必须手动设置一遍
        //单据状态,录入人,录入时间
        entity.setStatus(StockIncomeBill.NO_AUDITED); //设置未审核状态
        entity.setInputUser(UserContext.getCurrentUser());
        entity.setInputTime(new Date());
        //后台重新计算明细的小计和单据的总计
        BigDecimal totalNumber = BigDecimal.ZERO;
        BigDecimal totalAmount = BigDecimal.ZERO;
        for (StockIncomeBillItem item : entity.getItems()) {
            BigDecimal amount = item.getCostPrice().multiply(item.getNumber())
                    .setScale(2,RoundingMode.HALF_UP);
            item.setAmount(amount);
            totalNumber = totalNumber.add(item.getNumber());
            totalAmount = totalAmount.add(amount);
        }
        //累加到总计上
        entity.setTotalNumber(totalNumber);
        entity.setTotalAmount(totalAmount);
        //保存到数据库
        billMapper.insert(entity);
        //每个明细设置单据id,保存到数据库
        for (StockIncomeBillItem item : entity.getItems()) {
            item.setBillId(entity.getId());
            itemMapper.insert(item);
        }
    }




    @Override
    public void delete(Long id) {
        //判断当前单据必须是未审核状态
        StockIncomeBill old = billMapper.selectByPrimaryKey(id);
        if (old.getStatus() == StockIncomeBill.NO_AUDITED) {
            //先删除明细再删除单据
            billMapper.deleteItemsByBillId(id);
        }
        billMapper.deleteByPrimaryKey(id);
    }

    @Override
    public StockIncomeBill get(Long id) {
        return billMapper.selectByPrimaryKey(id);
    }


    @Override
    public void audit(Long id) {
        //判断当前单据必须是未审核状态
        StockIncomeBill bill = billMapper.selectByPrimaryKey(id);
        Depot depot = bill.getDepot(); //入的仓库
        if (bill.getStatus() == StockIncomeBill.NO_AUDITED) {
            //拿到当前单据的明细,存入数据库
            //拿到当前明细的商品
            for (StockIncomeBillItem item : bill.getItems()) {
                Product p = item.getProduct();
                //判断仓库中是否有商品
                ProductStock ps = psMapper.selectByProductIdAndDepotId(p.getId(), depot.getId());
                if (Optional.ofNullable(ps).isPresent()){
                    //如果有商品,执行更新操作
                    //重新计算数量,总金额,仓库价
                    BigDecimal amount = ps.getAmount().add(item.getAmount());
                    BigDecimal storeNumber = ps.getStoreNumber().add(item.getNumber());
                    BigDecimal price = amount.divide(storeNumber, RoundingMode.HALF_UP);
                    //更新三个数据
                    ps.setAmount(amount);
                    ps.setPrice(price);
                    ps.setStoreNumber(storeNumber);
                    //保存到数据库
                    psMapper.updateByPrimaryKey(ps);
                } else {
                    //没有库存,第一次进货
                    ps = new ProductStock();
                    ps.setProduct(p);
                    ps.setDepot(depot);
                    ps.setStoreNumber(item.getNumber());
                    ps.setPrice(item.getCostPrice());
                    ps.setAmount(item.getAmount());
                    //保存到数据库
                    psMapper.insert(ps);
                }
            }
        }
        bill.setStatus(StockIncomeBill.AUDITED);
        bill.setAuditor(UserContext.getCurrentUser());
        bill.setAuditTime(new Date());
        billMapper.audit(bill);
    }

    @Override
    public PageResult query(QueryObject qo) {
        Integer rows = billMapper.queryForCount(qo);
        if (rows == 0){
            return PageResult.EMPTY_RESULT;
        }
        List<StockIncomeBill> list = billMapper.queryForList(qo);
        PageResult result = new PageResult(qo.getCurrentPage(), qo.getPageSize(), list, rows);
        return result;
    }
}
